package ar.frba.utn.diseñosistemas.TP2;

import java.util.ArrayList;
import java.util.Hashtable;

public class AerolineaMock extends Aerolinea 
{
	private ArrayList<Asiento> asientos;
	private Hashtable<Asiento, Usuario> reservas;
	
	public AerolineaMock()
	{
		reservas = new Hashtable<Asiento, Usuario>();
		asientos = new ArrayList<Asiento>();
		asientos.add(new Asiento("EA342", "412", 1000023, Clase.Primera, Ubicacion.Centro, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));
		asientos.add(new Asiento("EA341", "411", 3000, Clase.Turista, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "22/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA343", "410", 26271, Clase.Ejecutivo, Ubicacion.Pasillo, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));
		asientos.add(new Asiento("EA345", "439", 23423, Clase.Primera, Ubicacion.Pasillo, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA344", "438", 10098, Clase.Turista, Ubicacion.Centro, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));
		asientos.add(new Asiento("EA346", "437", 76237, Clase.Turista, Ubicacion.Centro, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA347", "436", 1000023, Clase.Primera, Ubicacion.Pasillo, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));
		asientos.add(new Asiento("EA348", "435", 26256, Clase.Primera, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA349", "434", 6372, Clase.Turista, Ubicacion.Pasillo, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));
		asientos.add(new Asiento("EA310", "433", 7500, Clase.Primera, Ubicacion.Centro, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA311", "432", 9003, Clase.Ejecutivo, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA312", "431", 217781, Clase.Ejecutivo, Ubicacion.Centro, EstadoAsiento.Reservado,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "EZE", "PER"));	
		asientos.add(new Asiento("EA370", "435", 26256, Clase.Turista, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA370", "435", 26256, Clase.Ejecutivo, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA370", "435", 26256, Clase.Turista, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
		asientos.add(new Asiento("EA370", "435", 26256, Clase.Ejecutivo, Ubicacion.Ventanilla, EstadoAsiento.Disponible,"20/10/2012", "10:30", "21/10/2012", "04:28", this, "PER", "USA"));
	}
	
	@Override
	public void comprar(Asiento unAsiento, Usuario unUsuario) 
	{
		Asiento asiento = buscarAsiento(unAsiento);
		
		if (asiento != null)
		{
			this.validarComprar(asiento, unUsuario);
			asiento.setEstado(EstadoAsiento.Comprado);
		}
		else
			throw new RuntimeException("El asiento no existe");
	}

	@Override
	public ArrayList<Asiento> buscar(Busqueda unaBusqueda) 
	{
		ArrayList<Asiento> resultados = new ArrayList<Asiento>();
		
		for (Asiento asiento : this.asientos) 
		{
			if(asiento.getEstado() != EstadoAsiento.Comprado)
				resultados.add(asiento);
		}
		
		return resultados;
	}
	
	@Override
	public ArrayList<Asiento> buscarSinDestino(Busqueda unaBusqueda) 
	{
		ArrayList<Asiento> resultados = new ArrayList<Asiento>();
		
		for (Asiento asiento : this.asientos) 
		{
			if((asiento.getEstado() != EstadoAsiento.Comprado) && asiento.getOrigen().equals(unaBusqueda.getOrigen()))
				resultados.add(asiento);
		}
		
		return resultados;
	}

	@Override
	public void reservar(Asiento unAsiento, Usuario unUsuario) 
	{
		Asiento asiento = buscarAsiento(unAsiento);
		
		if (asiento != null)
		{
			this.validarReserva(asiento, unUsuario);
			asiento.setEstado(EstadoAsiento.Reservado);
			reservas.put(asiento, unUsuario);
		}
		else
			throw new RuntimeException("El asiento no existe");
	}

	@Override
	public Boolean estaReservado(Asiento unAsiento) 
	{
		Asiento asiento = buscarAsiento(unAsiento);
		if(asiento == null)
			throw new RuntimeException("No existe el asiento");
		
		return asiento.getEstado() == EstadoAsiento.Reservado;
	}

	private void validarComprar(Asiento unAsiento, Usuario unUsuario)
	{
		if (unAsiento.getEstado() == EstadoAsiento.Comprado)
			throw new RuntimeException("El asiento ya fue comprado");
		
		if (unAsiento.getEstado() == EstadoAsiento.Reservado)
		{
			if (this.reservas.get(unAsiento) != unUsuario)
				throw new RuntimeException("El asiento fue reservado por otro usuario");
		}
	}
	
	private void validarReserva(Asiento unAsiento, Usuario unUsuario)
	{
		if (unAsiento.getEstado() != EstadoAsiento.Disponible)
			throw new RuntimeException("Este asiento no puede ser reservado");
	}

	private Asiento buscarAsiento(Asiento unAsiento)
	{
		for (Asiento asiento : this.asientos) 
		{
			if(asiento.getCodigoVuelo().equalsIgnoreCase(unAsiento.getCodigoVuelo())
				&& asiento.getNumeroAsiento().equalsIgnoreCase(unAsiento.getNumeroAsiento()))
				return asiento;
		}
		
		return null;
	}

	void cambiarEstadoAsientoADisponible(Asiento asiento) 
	{
		this.buscarAsiento(asiento).setEstado(EstadoAsiento.Disponible);
	}
}
